package render;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.glu.GLU;

public class Shader {
	
	private int[] shaderIds;
	private int programId;
	private int ErrorCheckValue;
	
	public Shader()
	{
		
	}
	
	public int loadShader(String filename, int type)
	{
		StringBuilder shaderSource = new StringBuilder();
		int shaderID = 0;
		try{
			
			BufferedReader reader = new BufferedReader(new FileReader(filename));
			String line;
			
			while ((line = reader.readLine()) != null)
			{
				shaderSource.append(line).append("\n");
			}
			reader.close();
			
			
		}catch (IOException e)
		{
			
			System.err.println("Error in loading file");
			e.printStackTrace();
			System.exit(-1);
			
		}//
		
		shaderID = GL20.glCreateShader(type);
		GL20.glShaderSource(shaderID, shaderSource);
		GL20.glCompileShader(shaderID);
		
		return shaderID;
	}// loadShader
	
	
	
	public void setUpShaders(String[] shadersAddress,String[] shaderTypes,String[] infoNames)
	{
		//this shader setup will be able to setup any number of shaders
		int errorCheckValue = GL11.glGetError();
		
		shaderIds = new int[shadersAddress.length];
		//initialize shaderIds to the number of shader addresses
		
		
		if(shadersAddress.length==shaderTypes.length)//if the shader addresses and shader types are equal
			{
				programId = GL20.glCreateProgram();
				for(int sCounter =0;sCounter<shadersAddress.length; sCounter++)
				{
			
			//Load shader and attach it to the program
			if(shaderTypes[sCounter].equalsIgnoreCase("vertex"))
			{
				shaderIds[sCounter]=this.loadShader(shadersAddress[sCounter], GL20.GL_VERTEX_SHADER);
				GL20.glAttachShader(programId,shaderIds[sCounter]);
				
			}
			else if(shaderTypes[sCounter].equalsIgnoreCase("fragment"))
			{
				shaderIds[sCounter]=this.loadShader(shadersAddress[sCounter], GL20.GL_FRAGMENT_SHADER);
				GL20.glAttachShader(programId,shaderIds[sCounter]);
			}
			else
			{
				System.err.println("Shader not recognized");
				
				System.exit(-1);
				//if a shader other than the ones already recognized is entered
				//exit with an error
			}
			
			//link the program with the shaders
			
			
			
			//
			
				}//end for
				
				
				GL20.glLinkProgram(programId);
				
				
				for(int sCounter =0;sCounter<infoNames.length; sCounter++)
				{
					GL20.glBindAttribLocation(programId,sCounter,infoNames[sCounter]);
				}//end
				
				GL20.glValidateProgram(programId);
				ErrorCheckValue = GL11.glGetError();
					if(errorCheckValue!=GL11.GL_NO_ERROR)
					{
						System.out.println("ERROR - Could not create the shaders:" +
					GLU.gluErrorString(ErrorCheckValue));
						System.exit(-1);
					}
				
			}//end
		else
		{
			
				
			
			if(shadersAddress.length>shaderTypes.length)
			{
				
			System.err.println("More shader addresses provided then types");
			System.exit(-1);
			//if more shader addresses are provided then types exit with an error
			}
			else if(shadersAddress.length<shaderTypes.length)
			{
			
				System.err.println("More shader types provided then Shader addresses");
				System.exit(-1);
				// if more shader types are provided then types exit with an error
			}
			
			
			
			
		}//end
		
		//Load the vertex shader
		
		
	}//

	/**
	 * @return the programId
	 */
	public int getProgramId() {
		return programId;
	}

	/**
	 * @param programId the programId to set
	 */
	public void setProgramId(int programId) {
		this.programId = programId;
	}
	
	public int[] getShaderIds()
	{
	 
		return  shaderIds;
	
	}//end getShader
	public int getShaderIds(int idNum)
	{
	 
		return  shaderIds[idNum];
	
	}//end getShader
	
}
